package controller

import (
	"bookManage/dao/mysql"
	"bookManage/model"
	"crypto/sha256"
	"encoding/hex"
	"time"

	"github.com/dgrijalva/jwt-go"

	"github.com/gin-gonic/gin"
)

/**
@author hujianli
*/

// jwt 相关配置
const (
	jwtSecret     = "a0e9e841-b83f-46af-8cdf-0905cc8180ff" // 自定义密钥
	jwtExpiration = time.Hour * 24                         // token 有效期为一天
)

// 生成 JWT token
func generateJWTToken(userID uint) (string, error) {
	// 创建一个 token 对象
	token := jwt.New(jwt.SigningMethodHS256)

	// 设置载荷信息
	claims := token.Claims.(jwt.MapClaims)
	claims["id"] = userID
	claims["exp"] = time.Now().Add(jwtExpiration).Unix()

	// 签名生成最终的 token 字符串
	signedToken, err := token.SignedString([]byte(jwtSecret))
	if err != nil {
		return "", err
	}

	return signedToken, nil
}

// 密码加密函数
func encryptPassword(password string) string {
	hash := sha256.Sum256([]byte(password))
	encryptedPassword := hex.EncodeToString(hash[:])
	return encryptedPassword
}

// 比对密码函数
func comparePasswords(hashedPassword string, password string) bool {
	encryptedPassword := encryptPassword(password)
	return hashedPassword == encryptedPassword
}

// 注册
func RegisterHandler(c *gin.Context) {
	p := new(model.User)
	//参数校验
	if err := c.ShouldBindJSON(p); err != nil {
		c.JSON(400, gin.H{"err": err.Error()})
		return
	}
	// 这里应该是客户端已加密后的密码
	password := p.Password
	p.Password = encryptPassword(password)

	mysql.DB.Create(p)
	c.JSON(200, gin.H{"msg": p})
}

// 登录
func LoginHandler(c *gin.Context) {
	p := new(model.User)
	//参数校验
	if err := c.ShouldBindJSON(p); err != nil {
		c.JSON(400, gin.H{"err": err.Error()})
		return
	}

	//查找用户
	var user model.User
	result := mysql.DB.Where(&model.User{Username: p.Username}).First(&user)
	if result.Error != nil {
		c.JSON(403, gin.H{"msg": "用户名密码错误"})
		return
	}

	//比对密码
	if !comparePasswords(user.Password, p.Password) {
		c.JSON(403, gin.H{"msg": "用户名密码错误"})
		return
	}

	// 生成 JWT token
	token, err := generateJWTToken(user.Id)
	if err != nil {
		c.JSON(500, gin.H{"msg": "生成 token 失败"})
		return
	}

	// 更新 token 字段
	mysql.DB.Model(&user).Update("token", token)
	c.JSON(200, gin.H{"token": token})
}
